package com.zhangxu.microservice.system.biz.service.impl;

import com.zhangxu.microservice.system.biz.config.AuthTokenProperties;
import com.zhangxu.microservice.system.biz.util.JwtUtil;
import lombok.RequiredArgsConstructor;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import java.time.Duration;

/**
 * TokenService 管理 Token 的生成、验证、续期和移除。
 * 结合 Redis 实现登录态管理和 Token 有效期控制。
 */
@Service
@RequiredArgsConstructor
public class TokenService {

    private final RedissonClient redissonClient;
    private final AuthTokenProperties tokenProperties;
    private final JwtUtil jwtUtil;

    private static final String PREFIX = "auth:token:";

    /**
     * 生成 JWT Token，并写入 Redis 管理其有效期。
     *
     * @param userId   用户 ID
     * @param username 用户名
     * @return 生成的 JWT Token 字符串
     */
    public String generateAndCacheToken(Long userId, String username) {
        String token = jwtUtil.generateToken(userId, username);
        RBucket<Long> bucket = redissonClient.getBucket(PREFIX + token);
        bucket.set(userId, Duration.ofSeconds(tokenProperties.getTtl()));
        return token;
    }

    /**
     * 验证 Token 是否有效（是否存在于 Redis 中且未过期）。
     *
     * @param token JWT Token 字符串
     * @return 是否有效
     */
    public boolean isTokenValid(String token) {
        return redissonClient.getBucket(PREFIX + token).isExists();
    }

    /**
     * 刷新 Token 的过期时间（续期），用于滑动过期策略。
     * 在用户活跃操作时延长 Token 在 Redis 中的有效期。
     *
     * @param token JWT Token 字符串
     */
    public void refreshToken(String token) {
        RBucket<Object> bucket = redissonClient.getBucket(PREFIX + token);
        if (bucket.isExists()) {
            bucket.expire(Duration.ofSeconds(tokenProperties.getTtl()));
        }
    }

    /**
     * 移除 Token，用于登出或强制失效。
     *
     * @param token JWT Token 字符串
     */
    public void removeToken(String token) {
        redissonClient.getBucket(PREFIX + token).delete();
    }
}